package com.iraeta.service.sys.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iraeta.WeiXinConfig;
import com.iraeta.common.ServiceException;
import com.iraeta.entity.main.vo.WeiXinOAuthLogin;
import com.iraeta.entity.main.vo.WeiXinUserInfo;
import com.iraeta.uitl.HttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@Component
public class WeiXinService {
    private static final Logger logger = LoggerFactory.getLogger(WeiXinService.class);
    @Autowired
    WeiXinConfig weiXinConfig;

    private static String access_token = null;
    private static Date tokenExpireTime = null;

    private String ticket = null;
    private Date ticketExpireTime = null;

    public String getAccess_token() {
        if (null == access_token || new Date().getTime() > tokenExpireTime.getTime()) {
            return getAccessToken();
        } else {
            return access_token;
        }
    }
    private String getAccessToken(){
        String corpid = weiXinConfig.getCompId();   //企业id
        String secret = weiXinConfig.getAppSecret();
        try {
            String res = HttpUtils.sendGet("https://qyapi.weixin.qq.com/cgi-bin/gettoken", "corpid="+corpid+"&corpsecret="+secret);
            JSONObject jsonObject = JSON.parseObject(res);
            Object accesstoken = jsonObject.get("access_token");
            if (null != accesstoken) {
                access_token = accesstoken.toString();
                tokenExpireTime = DateUtil.offsetMinute(new Date(), 60);
            }
        } catch (Exception e) {
            e.printStackTrace();
            cleanTokenCache();
            throw new ServiceException("微信token获取失败");
        }
        return access_token;
    }
    private void cleanTokenCache() {
        access_token = null;
        tokenExpireTime = null;
    }

    /*获取微信ticket*/
    public String getJSAPITicket(String access_token) {
        if (null == ticket || new Date().getTime() > ticketExpireTime.getTime()) {
            return getTicket(access_token);
        } else {
            return ticket;
        }
    }

    private String getTicket(String access_token) {
        try {
            String res = HttpUtils.sendGet("https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket", "access_token=" + access_token);
            JSONObject jsonObject = JSON.parseObject(res);
            Object t = jsonObject.get("ticket");
            if (null != t) {
                ticket = jsonObject.get("ticket").toString();
                ticketExpireTime = DateUtil.offsetMinute(new Date(), 60);
            }
        } catch (Exception e) {
            e.printStackTrace();
            cleanTicketCache();
            throw new ServiceException("微信ticket获取失败");
        }
        return ticket;
    }

    private void cleanTicketCache() {
        ticket = null;
        ticketExpireTime = null;
    }

    /*获取微信随机串和签名*/
    private String[] strs = new String[] {
            "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
            "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"
    };
    public String createnRandomStr() {
        Random r = new Random();
        StringBuilder sb = new StringBuilder();
        int length = strs.length;
        for (int i = 0; i < 15; i++) {
            sb.append(strs[r.nextInt(length - 1)]);
        }
        return sb.toString();
    }
    public String getSignature(String ticket, String noncestr, long timestamp, String url) {
        String restule = "";
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("jsapi_ticket=").append(ticket).append("&")
                .append("noncestr=").append(noncestr).append("&")
                .append("timestamp=").append(timestamp).append("&")
                .append("url=").append(url.indexOf("#") >= 0 ? url.substring(0, url.indexOf("#")) : url);
        restule = stringBuilder.toString();
        return SHA1(restule);
    }
    public String SHA1(String str) {
        try {
            MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1"); //如果是SHA加密只需要将"SHA-1"改成"SHA"即可
            digest.update(str.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexStr = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexStr.append(0);
                }
                hexStr.append(shaHex);
            }
            return hexStr.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
    public Map<String, Object> getWxReadyConfig(String url){
        Map<String, Object> map = new HashMap<>();
        try {
            String access_token = this.getAccess_token();
            String jsapiTicket = this.getJSAPITicket(access_token);
            String noncestr = this.createnRandomStr();
            long timestamp = new Date().getTime();
            String signature = this.getSignature(jsapiTicket, noncestr, timestamp, url);
            map.put("appid", weiXinConfig.getCompId());
            map.put("jsapi_ticket", jsapiTicket);
            map.put("noncestr", noncestr);
            map.put("timestamp", timestamp);
            map.put("signature", signature.toLowerCase());
        }catch (Exception e){
            e.printStackTrace();
        }
        return map;
    }

    public WeiXinOAuthLogin getUserIdByCode(String code){
        String token = this.getAccess_token();
        try{
            String res = HttpUtils.sendGet("https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo", "access_token="+token+"&code="+code);
            JSONObject jsonObject = JSON.parseObject(res);
            logger.info(jsonObject.toJSONString());
            String userid = jsonObject.getString("userid");
            String user_ticket = jsonObject.getString("user_ticket");
            if (null == userid) {
                throw new ServiceException("微信身份获取失败1");
            }
            return new WeiXinOAuthLogin(userid, user_ticket);
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("微信身份获取失败1");
        }
    }

    public WeiXinUserInfo getWeiXinUserInfo(String user_ticket){
        String token = this.getAccess_token();
        try {
            JSONObject body = new JSONObject();
            body.put("user_ticket", user_ticket);
            String res = HttpUtils.httpPost("https://qyapi.weixin.qq.com/cgi-bin/auth/getuserdetail?access_token=" + token, body.toJSONString());
            JSONObject jsonObject = JSON.parseObject(res);
            logger.info(jsonObject.toJSONString());
            String userid = jsonObject.getString("userid");
            String mobile = jsonObject.getString("mobile");
            String avatar = jsonObject.getString("avatar");
            if(null == userid){
                throw new ServiceException("微信身份获取失败2");
            }
            return new WeiXinUserInfo(userid, mobile, avatar);
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("微信身份获取失败2");
        }
    }

    public String setWxUserTextMessage(String toUser, String content){
        String token = this.getAccess_token();
        try {
            JSONObject body = new JSONObject();
            body.put("agentid", weiXinConfig.getAppId());
            body.put("msgtype", "text");
            body.put("safe", 0);
            body.put("enable_id_trans", 0);
            body.put("enable_duplicate_check", 0);
            body.put("duplicate_check_interval", 1800);

            body.put("touser", toUser);
            Map<String, String> text = new HashMap<>();
            text.put("content", content);
            body.put("text", text);
            String res = HttpUtils.httpPost(" https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + token, body.toJSONString());
            JSONObject jsonObject = JSON.parseObject(res);
            int errcode = jsonObject.getIntValue("errcode");
            if(errcode!=0){
                throw new ServiceException(jsonObject.getString("errmsg"));
            }
        }catch (Exception e){
            e.printStackTrace();
            return e.getMessage();
        }
        return "";
    }
}
